#ifndef _AUSER_H_
#define _AUSER_H

#include <iostream>
#include <string>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <memory.h>
#include <jsoncpp/json/json.h>
#include "config.h"
#include "database.h"
using namespace std;

// 用户对象
class AUser
{
private:
    int fd;                      // 对象句柄
    struct epoll_event ev;       // 监听事件
    char temporary[BUF_MAX_LEN]; // 数据存放区
    char mark;                   // 行为标记
    int epFd;                    // 内核监听句柄
public:
    // 函数

    // 为整个类添加内核句柄
    void SetEpfd(int fd)
    {
        epFd = fd;
    }

    // 初始化
    void UserSet(int Ufd, int EPOLLIN, int efd)
    {
        fd = Ufd;
        ev.events = EPOLLIN;
        epFd = efd;
    }

    void getMag()
    {
        memset(temporary, 0, BUF_MAX_LEN);
        recv(fd, &temporary, BUF_MAX_LEN, 0);
        mark = temporary[0];
    }
    // 注册
    void server_register(const Json::Value &val)
    {
        Json::Value response;

        ChatDatabase::getChatDatabase()->my_database_connect();

        // 向mysql注册，-1表示sql语句失败了，否则注册成功
        string userid = ChatDatabase::getChatDatabase()->my_database_user_register(val["nickname"].asString(), val["password"].asString());
        if ("false" == userid)
        {
            response["cmd"] = REGISTER;
            response["result"] = _MYSQL_ERROR;
            return;
        }
        else
        {
            ChatDatabase::getChatDatabase()->my_database_user_getstate(userid, 2);
            response["cmd"] = REGISTER;
            response["loginid"] = userid;
            response["result"] = REGISTER_SUCCESS;
        }
        ChatDatabase::getChatDatabase()->my_database_disconnect();

        Json::FastWriter writer; // 封装json

        const string str = writer.write(response);
        char buf[BUF_MAX_LEN] = "";
        strcpy(buf, str.c_str());
        cout << buf << endl;
        if (send(fd, buf, BUF_MAX_LEN, 0) == -1)
        {
            perror("数据发送失败\n");
        }
    }
    // 登录
    void server_login(const Json::Value &val)
    {
        Json::Value response;
        ChatDatabase::getChatDatabase()->my_database_connect();
        // 判断用户是否存在
        string retuid;
        if (ChatDatabase::getChatDatabase()->my_database_user_exist(val["loginid"].asString()))
        {

            cout << val["loginid"].asString() << endl;
            cout << val["password"].asString() << endl;
            int ret = ChatDatabase::getChatDatabase()->my_database_user_confirm(val["loginid"].asString(), val["password"].asString());

            if (ret >= 0)
            {
                if (ret == 1)
                {
                    response["cmd"] = LOGIN;
                    response["result"] = LOGIN_PASSWORD_ERROR;
                }
                else if (ret == 2)
                {
                    response["cmd"] = LOGIN;
                    response["result"] = LOGIN_USER_NONEXISTENCE;
                }
                else
                {
                    Oline_map::getmap()->insertm_map(val["loginid"].asString(), fd);
                    // 登录成功修改用户状态
                    ChatDatabase::getChatDatabase()->my_database_user_getstate(val["loginid"].asString(), 1);
                    //   获取用户个人信息
                    User *usinfo = ChatDatabase::getChatDatabase()->my_database_user_getmessage(val["loginid"].asString());

                    Json::Value user;
                    user["loginid"] = Json::Value(usinfo->loginid);
                    user["nickname"] = Json::Value(usinfo->nickname);
                    user["signature"] = Json::Value(usinfo->signature);
                    user["sex"] = Json::Value(usinfo->sex);
                    user["birthday"] = Json::Value(usinfo->birthday);
                    user["pthone"] = Json::Value(usinfo->pthone);
                    user["email"] = Json::Value(usinfo->email);
                    user["headport"] = Json::Value(usinfo->headport);
                    user["age"] = Json::Value(usinfo->age);
                    user["city"] = Json::Value(usinfo->city);

                    response["user"].append(user);

                    //  获取用户好友信息
                    map<const string, Friends> frinfo = ChatDatabase::getChatDatabase()->my_database_getfriends(val["loginid"].asString());
                    Json::Value friendjs;
                    for (auto i = frinfo.begin(); i != frinfo.end(); i++)
                    {
                        friendjs["friendloginid"] = Json::Value(i->first);
                        friendjs["firendid"] = Json::Value(i->second.firendid);
                        friendjs["name"] = Json::Value(i->second.name);
                        friendjs["FriendGroups"] = Json::Value(i->second.FriendGroups);

                        response["friends"].append(friendjs);
                    }

                    response["cmd"] = LOGIN;

                    response["result"] = LOGIN_SUCCESS;
                }
            }
            else
            {
                response["cmd"] = LOGIN;
                response["result"] = _MYSQL_ERROR;
            }
        }
        else
        {
            response["cmd"] = LOGIN;
            response["result"] = LOGIN_USER_NONEXISTENCE;
        }
        ChatDatabase::getChatDatabase()->my_database_disconnect();

        Json::FastWriter writer; // 封装json
        string str = writer.write(response);

        char buf[BUF_MAX_LEN] = "";
        strcpy(buf, str.c_str());
        cout << buf << endl;
        if (send(fd, buf, BUF_MAX_LEN, 0) == -1)
        {
            perror("数据发送失败\n");
        }
    }
    // 聊天
    void transferMsg(const Json::Value &val)
    {
        Json::Value response;
        ChatDatabase::getChatDatabase()->my_database_connect();
        // 判断receiver是否在线
        int x = ChatDatabase::getChatDatabase()->my_database_user_setstate(val["receiver"].asString());
        if (x == 1)
        {
            //  消息写入数据库
            ChatDatabase::getChatDatabase()->my_database_write_offlineMsg(val);
            //  包装转发消息
            response["cmd"] = CHAT;
            response["sender"] = val["sender"];
            response["message"] = val["message"];
            response["time"] = val["time"];
            response["result"] = CHAT_SUCCESS;

            Json::FastWriter writer;
            const string str = writer.write(response);
            char buf[BUF_MAX_LEN] = "";
            strcpy(buf, str.c_str());
            cout << buf << endl;
            // 得到对方fd
            int receiverfd = Oline_map::getmap()->findm_map(val["receiver"].asString());
            //  转发
            if (send(receiverfd, buf, BUF_MAX_LEN, 0) == -1)
            {
                perror("数据发送失败\n");
            }
        }
        else
        {
            //  消息写入数据库
            ChatDatabase::getChatDatabase()->my_database_write_offlineMsg(val);
            //  封装json
            response["cmd"] = CHAT;
            response["result"] = CHAT_OFF_ONLINE;

            Json::FastWriter writer;
            const string str = writer.write(response);
            char buf[BUF_MAX_LEN] = "";
            strcpy(buf, str.c_str());
            cout << buf << endl;
            //  发给发送者
            if (send(fd, buf, BUF_MAX_LEN, 0) == -1)
            {
                perror("数据发送失败\n");
            }
        }
        ChatDatabase::getChatDatabase()->my_database_disconnect();
    }
    //  退出
    void quit_login(const Json::Value &val)
    {
        Json::Value response;
        response["cmd"] = QUIT;
        ChatDatabase::getChatDatabase()->my_database_connect();
        // 更改状态

        if (ChatDatabase::getChatDatabase()->my_database_user_getstate(val["loginid"].asString(), 2) != 0)
        {
            response["result"] = QUIT_ERROR;
        }
        else
        {
            // 移除fd
            Oline_map::getmap()->detem_map(val["loginid"].asString());
            //移除内核监听
            ev.events = EPOLLIN | EPOLLET;
            epoll_ctl(epFd,EPOLL_CTL_DEL,fd,&ev);
            close(fd);
            
            response["result"] = QUIT_SUCCESS;
        }
        Json::FastWriter writer;
        const string str = writer.write(response);
        char buf[BUF_MAX_LEN] = "";
        strcpy(buf, str.c_str());
        cout << buf << endl;
        //  发给发送者
        if (send(fd, buf, BUF_MAX_LEN, 0) == -1)
        {
            perror("数据发送失败\n");
        }
    }
    // 更新个人数据
    void updata_user(const Json::Value &val)
    {
        Json::Value response;
        response["cmd"] = UPDATA;
        ChatDatabase::getChatDatabase()->my_database_connect();
        User usinfo;
        usinfo.age = val["age"].asInt();
        usinfo.birthday = val["birthday"].asString();
        usinfo.city = val["city"].asString();
        usinfo.email = val["email"].asString();
        usinfo.headport = val["headport"].asString();
        usinfo.loginid = val["loginid"].asString();
        usinfo.nickname = val["nickname"].asString();
        usinfo.pthone = val["pthone"].asString();
        usinfo.sex = val["sex"].asString();
        usinfo.signature = val.asString();

        ChatDatabase::getChatDatabase()->my_database_user_setmessage(usinfo);
        response["result"] = UPDATA_SUCCESS;
        Json::FastWriter writer;
        const string str = writer.write(response);
        char buf[BUF_MAX_LEN] = "";
        strcpy(buf, str.c_str());
        cout << buf << endl;
        //  发给发送者
        if (send(fd, buf, BUF_MAX_LEN, 0) == -1)
        {
            perror("数据发送失败\n");
        }
    }
    //  添加好友
    void addfriend(const Json::Value &val)
    {
        Json::Value response;
        response["cmd"] = FRIEND;
        ChatDatabase::getChatDatabase()->my_database_connect();
        int x = ChatDatabase::getChatDatabase()->add_friend(val["loginid"].asString(), val["friendid"].asString(), val["ownname"].asString(), val["friname"].asString());
        if (x == 1)
        {
            response["result"] = ADDFRIEND_SUCCESS;
        }
        else
        {
            response["result"] = ADDFRIEND_ERROR;
        }
        Json::FastWriter writer;
        const string str = writer.write(response);
        char buf[BUF_MAX_LEN] = "";
        strcpy(buf, str.c_str());
        cout << buf << endl;
        //  发给发送者
        if (send(fd, buf, BUF_MAX_LEN, 0) == -1)
        {
            perror("数据发送失败\n");
        }
    }
    //搜索用户
    void index_user(const Json::Value &val)
    {
        Json::Value response;
        response["cmd"] = INDEX;
        ChatDatabase::getChatDatabase()->my_database_connect();
        vector<User> uservector = ChatDatabase::getChatDatabase()->my_database_user_find(val["nickname"].asString());
        ChatDatabase::getChatDatabase()->my_database_disconnect();
        if (!uservector.empty())
        {
            for (auto i = uservector.begin(); i < uservector.end(); i++)
            {
                Json::Value user;
                user["loginid"] = Json::Value(i->loginid);
                user["nickname"] = Json::Value(i->nickname);

                response["user"].append(user);
            }
            response["result"] = INDEX_SUCCESS;
        }
        else
        {
            response["result"] = INDEX_NULL;
        }
        Json::FastWriter writer;
        const string str = writer.write(response);
        char buf[BUF_MAX_LEN] = "";
        strcpy(buf, str.c_str());
        cout << buf << endl;
        //  发给发送者
        if (send(fd, buf, BUF_MAX_LEN, 0) == -1)
        {
            perror("数据发送失败\n");
        }
    }
    void Auser_bing()
    {
        bool mark = true;
        while (mark)
        {
            getMag();
            cout << this->temporary << endl;
            Json::Reader reader; // 解析json
            Json::Value val;     // 解析的json数据
            string str(this->temporary);
            if (!reader.parse(str, val))
            {
                cout << str << endl;
                cout << "parse failure" << endl;
                return;
            }
            int cmd = val["cmd"].asInt();
            switch (cmd)
            {

            case REGISTER:
                // 注册
                server_register(val);
                break;

            case LOGIN:
                // 登录并获取用户数据
                server_login(val);
                break;

            case CHAT:
                // 用户聊天转发
                transferMsg(val);
                break;

            case FRIEND:
                // 添加好友
                addfriend(val);
                break;

            case UPDATA:
                // 更新个人数据
                updata_user(val);
                break;
            case INDEX:
                // 搜索好友
                index_user(val);
                break;
            case QUIT:
                //  退出登录
                quit_login(val);
                mark = false;
                break;
            default:
                break;
            }
        }
    }
};

#endif